
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;

public class UDPServiceThread extends Thread {
	public static final String ACK = "ACK";

	private Integer nPut=0, nGet=0, nFilter=0, nResize=0;

	private DatagramSocket socket;
	private DatagramPacket packet;
	private int dimFisier ;
	private String operatie;
	private String extensie;
	
	public ArrayList<Integer> vectorFisiere;
	public UDPServiceThread(DatagramSocket socket, DatagramPacket packet, int dim, ArrayList<Integer> vectorFisie,String _operatie,String _extensie) {
		this.socket = socket;
		this.packet = packet;
		this.dimFisier = dim;
		this.vectorFisiere = vectorFisie;
		this.operatie = _operatie;
		this.extensie = _extensie;
		
	}
	
	public void setStat(Integer nPut, Integer nGet, Integer nFilter, Integer nResize) {
		this.nPut = nPut;
		this.nGet = nGet;
		this.nFilter = nFilter;
		this.nResize = nResize;
	}
	
	public static String readFileAsString(String filePath) throws java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        BufferedReader reader = new BufferedReader(
                new FileReader(filePath));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }
	
	public void run() {
		
		System.out.println("deci am operatia " + this.operatie);
		if(this.operatie.equalsIgnoreCase("put"))
		{
			nPut++;
			byte[] fisierByte = new byte[this.dimFisier];
			
			fisierByte = packet.getData();
			
			System.out.println("Primesc date despre fisire " + this.dimFisier);
			
			
			//String receivedData = new String(packet.getData(), 0, packet.getLength());
			//System.out.println("[UDPServiceThread-" + this.hashCode() + "] Received: " + receivedData);
			
			// Simulate the processing of the request by sleeping a bit.
			
			 try
		     {
			      FileOutputStream fos = new FileOutputStream("Storage/" + (vectorFisiere.size() + 1)  + this.extensie);
			     
			      /*
			       * To write byte array to a file, use
			       * void write(byte[] bArray) method of Java FileOutputStream class.
			       *
			       * This method writes given byte array to a file.
			       */
			     
			       fos.write(fisierByte);
			     
			       vectorFisiere.add(vectorFisiere.size() + 1);
			      /*
			       * Close FileOutputStream using,
			       * void close() method of Java FileOutputStream class.
			       *
			       */
			     
			       fos.close();
		     
		     }
		     catch(FileNotFoundException ex)
		     {
		    	 System.out.println("FileNotFoundException : " + ex);
		     }
		     catch(IOException ioe)
		     {
		    	 System.out.println("IOException : " + ioe);
		     }
			 
			try {
				Thread.sleep(500);
			} catch (Exception e) {}
			
			// Send an answer back.
			InetAddress addr = packet.getAddress();
			int port = packet.getPort();
			
			
			byte ans[] = (""+ vectorFisiere.size()).getBytes();
			DatagramPacket ansPacket = new DatagramPacket(ans, 0, ans.length, addr, port);
			
			try {
				this.socket.send(ansPacket);
			} catch (Exception e) {
				System.err.println("[UDPServiceThread-" + this.hashCode() + "] Exceptie la trimiterea raspunsului: " + e);
				e.printStackTrace();
			}
		}
		else{
			if(this.operatie.equalsIgnoreCase("get"))
			{
				nGet++;
				String value = new String (packet.getData());
				
				String[] elemente = value.split(" ");
				
				File file = new File("Storage/"+elemente[1]);
			    byte [] fileContent = new byte[1];
			    try
			    {
			    	//create FileInputStream object
			    	FileInputStream fin = new FileInputStream(file);
			    	fileContent = new byte[(int)file.length()];
			     
			    	fin.read(fileContent);
			     
			    }
			    catch(FileNotFoundException e)
			    {
			      System.out.println("File not found" + e);
			    }
			    catch(IOException ioe)
			    {
			      System.out.println("Exception while reading the file " + ioe);
			    }
			    
			 // Send an answer back.
				InetAddress addr = packet.getAddress();
				int port = packet.getPort();
				
				byte ans2[] = ("" + fileContent.length).getBytes();
				DatagramPacket ansPacket2 = new DatagramPacket(ans2, 0, ans2.length, addr, port);
				
				try {
					this.socket.send(ansPacket2);
				} catch (Exception e) {
					System.err.println("[UDPServiceThread-" + this.hashCode() + "] Exceptie la trimiterea raspunsului: " + e);
					e.printStackTrace();
				}
				
				
				byte ans[] = fileContent;
				DatagramPacket ansPacket = new DatagramPacket(ans, 0, ans.length, addr, port);
				
				try {
					this.socket.send(ansPacket);
				} catch (Exception e) {
					System.err.println("[UDPServiceThread-" + this.hashCode() + "] Exceptie la trimiterea raspunsului: " + e);
					e.printStackTrace();
				}
			    
			    
			}else
			{
				if(this.operatie.equalsIgnoreCase("filter"))
				{
					nFilter++;
					String value = new String (packet.getData());
					
					String[] elemente = value.split(" ");
					String numeFiltru = elemente[1];
					this.extensie = elemente[2].substring(elemente[2].indexOf('.'));
					
					String numeFisierNou = "";
					System.out.println("trebuie sa am filtrul " + numeFiltru + " si valuarea " + value);
					//trebuie creat noul fisier
					if(numeFiltru.contains("blur"))
					{
						numeFisierNou =  DImageProcessor.blurImg("Storage/"+elemente[2]);
					}
					else{ 
						if(numeFiltru.contains("sharpern"))
						{
							numeFisierNou =  DImageProcessor.sharpenImg("Storage/"+elemente[2]);
						}
						else{
							if(numeFiltru.contains("flip"))
							{
								numeFisierNou =  DImageProcessor.flipImg("Storage/"+elemente[2]);
							}
						}
					}
					
					
						
				
					try {
						Thread.sleep(500);
					} catch (Exception e) {}
					
					// Send an answer back.
					InetAddress addr = packet.getAddress();
					int port = packet.getPort();
					
					
					byte ans[] = (""+ numeFisierNou.substring(numeFisierNou.indexOf('/')+1)).getBytes();
					DatagramPacket ansPacket = new DatagramPacket(ans, 0, ans.length, addr, port);
					
					try {
						this.socket.send(ansPacket);
					} catch (Exception e) {
						System.err.println("[UDPServiceThread-" + this.hashCode() + "] Exceptie la trimiterea raspunsului: " + e);
						e.printStackTrace();
					}
					
				}else{
					if(this.operatie.equalsIgnoreCase("resize"))
					{
						nResize++;
						String value = new String (packet.getData());
						
						String[] elemente = value.split(" ");
						String lungimeResize = elemente[1];
						String latimeResize = elemente[2];
						this.extensie = elemente[3].substring(elemente[3].indexOf('.'));
						
						//trebuie creat noul fisier
						String numeFisierNou = "";
						//trebuie creat noul fisier
						
						numeFisierNou = DImageProcessor.resizeImg("Storage/" + elemente[3], Integer.parseInt(lungimeResize), Integer.parseInt(latimeResize));
						try {
							Thread.sleep(500);
						} catch (Exception e) {}
						
						// Send an answer back.
						InetAddress addr = packet.getAddress();
						int port = packet.getPort();
						
						
						byte ans[] =  (""+ numeFisierNou.substring(numeFisierNou.indexOf('/')+1)).getBytes();
						DatagramPacket ansPacket = new DatagramPacket(ans, 0, ans.length, addr, port);
						
						try {
							this.socket.send(ansPacket);
						} catch (Exception e) {
							System.err.println("[UDPServiceThread-" + this.hashCode() + "] Exceptie la trimiterea raspunsului: " + e);
							e.printStackTrace();
						}
					}
				}
			
			}
		}
		
	}
}
